#ifndef __TASK_UTILS_NLQ3KVW5
#define __TASK_UTILS_NLQ3KVW5

#include <sys/mman.h>

#include "cms_msg.h"
#include "cms_common.h"
#include "libmdm.h"

#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif

#define CMS_NOTIFY_PRORITY_INTURRUPT_HANDLER    0
#define CMS_NOTIFY_PRORITY_REALTIME             1
#define CMS_NOTIFY_PRORITY_HIGHEST              2
#define CMS_NOTIFY_PRORITY_MEDIAN               50
#define CMS_NOTIFY_PRORITY_LOWEST               100

#define CMS_OBJECT_RECURSIVE_FLAG 	(1 << 0) /*flag for object interest recursive child object*/

/*Macro and parameters for cms task timer*/
#define WAN_PHYTYPE_PON 1
#define WAN_PHYTYPE_ETH 2
#define MSECS_IN_SEC  1000
#define NSECS_IN_USEC 1000
#define NSECS_IN_MSEC 1000000
#define NSECS_IN_SEC 1000000000
#define IS_EARLIER_THAN(a, b) (((a)->sec < (b)->sec) || (((a)->sec == (b)->sec) && ((a)->nsec < (b)->nsec)))

//extern pthread_mutex_t cms_tmr_mtx;
extern void *cmsTmrHandle;
extern uint64_t preUpBytes;
extern uint64_t preDownBytes;
extern void *cmsTmrHandleLanHostSpeed;

typedef struct cmsEventLock_s{
	pthread_mutex_t mutex;
	pthread_mutexattr_t mutexAttr;
}cmsEventLock_t;


/*structure for background module to register event*/
typedef struct cmsEventRegData_s{
	char *name;
	int (*func)();
	uint32_t priority;
	uint32_t eventId[];
}cmsEventRegData_t;

typedef struct cmsEventHandlerListEntry_s{
	struct cmsEventHandlerListEntry_s *prev;
	struct cmsEventHandlerListEntry_s *next;
	uint32_t priority;
	char *eventHandlerName;
	int	(*handler)(uint32_t eventId, uint32_t typeSizeOfValue, void *eventContent);
}cmsEventHandlerListEntry_t;

typedef struct cms_eventListEntry_s{
	 struct cms_eventListEntry_s *prev;
	 struct cms_eventListEntry_s *next;
	 uint32_t eventId;
	 struct cmsEventHandlerListEntry_s *eventHandlerList;
}cms_eventListEntry_t;

/*structure for background module to register object*/
typedef struct cmsConfigRegData_s{
	char *name;
	int	 (*func)();
	uint32_t priority;
	uint32_t objectId[];
}cmsConfigRegData_t;

typedef struct cms_configChgArg_s{
	struct cms_configChgArg_s *prev;
	struct cms_configChgArg_s *next;
	event_t *event;
	value_t *eventContent;
	void *oldObjData;
	objActionType_t objAction;
}cms_configChgArg_t;

typedef struct cms_objChgFuncList_s{
	struct cms_objChgFuncList_s *prev;
	struct cms_objChgFuncList_s *next;
	int (*confgLoader)(void *ptr);
	char *name;
	uint32_t priority;
	uint32_t funcFlag;	//recursive flag, if object set flag CMS_TASKMODULE_FUNC_RECURSIVE, this flag is 1, else is 0.
	//uint32_t execFlag;
}cms_objChgFuncList_t;


typedef struct cms_objectListEntry_s{
	struct cms_objectListEntry_s *prev;
	struct cms_objectListEntry_s *next;
	uint32_t objectId;
	struct cms_objChgFuncList_s *objChgFuncList;
}cms_objectListEntry_t;


/*struct for record obj change*/
typedef struct cmsObjChgList_s{
	struct cmsObjChgList_s *prev;
	struct cmsObjChgList_s *next;
	uint32_t realId;
	uint32_t objId;
	uint64_t objIA;
	//uint32_t priority;
	void 	*oldData;
	void	*newData;
	objActionType_t objAction;
	//int		(*func)();
}cmsObjChgList_t;

typedef struct cms_multiObjTask_s{
	struct cms_multiObjTask_s *prev;
	struct cms_multiObjTask_s *next;
	char *taskName;
	int (*taskFunc)(void *ptr);
	cms_configChgArg_t *objChgArgList;
}cms_multiObjTask_t;


/*structure for cmdline service*/
typedef struct cmsTask_cmdServiceRegData_s{
	char *name;
	int (*func)();
	uint32_t priority;
	uint32_t cmdServiceCode[];
}cmsTask_cmdServiceRegData_t;

typedef struct cmsTask_cmdHandlerList_s{
	struct cmsTask_cmdHandlerList_s *prev;
	struct cmsTask_cmdHandlerList_s *next;
	uint32_t priority;
	char *cmdHandlerName;
	int (*handler)(uint32_t cmd, value_t *cmdContent);
}cmsTask_cmdHandlerList_t;

typedef struct cmsTask_cmdList_s{
	struct cmsTask_cmdList_s *prev;
	struct cmsTask_cmdList_s *next;
	uint32_t cmd;
	struct cmsTask_cmdHandlerList_s *cmdHandlerList;
}cmsTask_cmdList_t;


/*cms task global context parameter*/
typedef struct cmsTaskContext_s{
	uint32_t moduleId;
	cmsBoolean dbusFlag;
	struct cms_eventListEntry_s *eventList;	  	/*event of concern*/
	struct cms_objectListEntry_s *objRegList;		/*config reg obj list*/
	struct cmsObjChgList_s *objChgList;			/*object change list*/
	struct cmsTask_cmdList_s *cmdServiceList;
}cmsTaskContext_t;

typedef struct objChgInfo_s{
	uint32_t objId;							/*The object id of object which has been changed*/
	uint32_t iNodeObjId;						/*index object id*/
	uint32_t indexDepth;						/*The index depth of object which has been changed, object index layer numbers, i.i.i*/
	uint32_t objIndexValue[];					/*every layer number include parent object*/
}objChgInfo_t;

typedef struct objSubcribe_s{
	struct objSubcribe_s *prev;
	struct objSubcribe_s *next;
	uint32_t objId;
}objSubcribe_t;


/*structure for cms task timer*/
typedef void (*cmsTimerEventHandler)(void*);

typedef struct
{
   uint32_t sec; 
   uint32_t nsec; 
}cmsTimestamp;

typedef struct cms_timer_event
{
   struct cms_timer_event *next;    
   cmsTimestamp expireTms; 
   cmsTimerEventHandler func;
   void * ctxData;
   char name[64];
} cmsTimerEvent;

typedef struct
{
   cmsTimerEvent *events;
   uint32_t eNumber;
   pthread_mutex_t tmr_mtx;
   int running;
} cmsTimerHandle;

/*API*/
void cmsTask_moduleInit(void);
void cmsTask_configLoadHandle(void);
void *cmsTask_configLoadSecHandle(void *arg);
void cmsTask_preConfig(void);

void cmsTask_registerSignal(void);
void cmsTask_dumpRegInfo(void);
int cmsTask_regEventToCms(const cmsEventRegData_t *regEvent[]);
int cmsTask_regObjectToCms(const cmsConfigRegData_t *regObject[]);
int cmsTask_regCmdServiceToCms(const cmsTask_cmdServiceRegData_t *regCmd[]);
int cmsTask_handleEvent(uint32_t eventId, uint32_t typeSizeOfValue, void *eventValue);
int cmsTask_collectObjChg(objectChgData_t *objData);
int cmsTask_handleObjChg(cmsObjChgList_t *objChgList, cmsBoolean isMutliObj);
int cmsTask_handleCmdService(cmdService_t *cmdService);
int cmsTask_objectStats(uint32_t OID, uint64_t IA);

cms_eventListEntry_t *cmsTask_getEventById(uint32_t eventId);
cms_objectListEntry_t *cmsTask_getObjectById(uint32_t objId);
void cmsTask_initEventLock(void);
void cmsTask_deInitEventLock(void);
void cmsTask_cleanUp(void);


/*api for task module*/
uint64_t  GenerateIA(uint32_t highV, uint32_t lowV);
objChgInfo_t *getObjInfoByIA(uint32_t objID , uint64_t objIA);

unsigned char a2x(const char c);
void str2MAC(unsigned char *mac, char *str);

cms_common_content_t *getCmsCommonCX();

#ifdef DBUS_OBJECT_NOTIFY
 int resetDbusObj(void);

 void dbusObjSubscribe(int numOfObj, uint32_t *objPtr);
 #endif

/*api for cms task timer*/
void *cmsTaskTimerHandle(void *arg);
 int cms_Tmr_init(void **tmrHandle);
 void cms_Tmr_cleanup(void **handle);
 void cmsTimerWanSpeedCountCalculateTask();
 int cms_Tmr_isEventPresent(const void *handle, cmsTimerEventHandler func, void *ctxData);
 void cms_Tms_get(cmsTimestamp *tms);
void *cmsTaskTimerHandleLanHostSpeed(void *arg);
#ifdef GC_XML_UPDATE_SUPPORT
void cmsTask_updateXml(void);
#endif


#endif /* end of include guard: __TASK_UTILS_NLQ3KVW5 */
